package rpc.frame.demo;

import io.netty.channel.socket.ServerSocketChannelConfig;
import lombok.extern.slf4j.Slf4j;

import javax.net.ServerSocketFactory;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;

@Slf4j
public class NioServer {
    /**
     * nio 服务端端
     * 1.创建serverSocket
     * 2.创建selector 监听
     * 3.客户段向serverSocket 注册时 创建socket 并且向监听器注册 read 事件
     * 4.处理事件
     * @param args
     */
    public static void main(String[] args) {
        try {
            ServerSocketChannel serverSocket = ServerSocketChannel.open();
            serverSocket.bind(new InetSocketAddress(9999));//绑定端口
            serverSocket.configureBlocking(false);//是否阻塞
            Selector selector = Selector.open();
            serverSocket.register(selector, SelectionKey.OP_ACCEPT);//监听注册事件
            while (true){
                int select = selector.select();
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()){
                    SelectionKey next = iterator.next();
                    iterator.remove();
                    processSelectionKey(next,selector);
                }
            }

        } catch (IOException e) {
            log.error("nio error msg={}",e);
            throw new RuntimeException(e);
        }

    }

    public static void processSelectionKey(SelectionKey selectionKey,Selector selector) throws IOException {
        if(selectionKey.isValid()){
            //如果是连接事件
            if(selectionKey.isAcceptable()){
                ServerSocketChannel serverSocketChannel=(ServerSocketChannel) selectionKey.channel();
                SocketChannel socketChannel = serverSocketChannel.accept();
                socketChannel.configureBlocking(false);
                socketChannel.register(selector,SelectionKey.OP_READ);//注册read 事件
                return;
            }
            //如果是channel 有数据可读
            if(selectionKey.isReadable()){
                SocketChannel channel = (SocketChannel) selectionKey.channel();
                ByteBuffer byteBuffer= ByteBuffer.allocate(1024);
                int read=channel.read(byteBuffer);
                if(read>0){
                    //读取的时候需要将指针翻转
                    byteBuffer.flip();
                    byte[] bytes=new byte[byteBuffer.remaining()];
                    byteBuffer.get(bytes);
                    String msg=new String(bytes, Charset.defaultCharset());
                    System.out.printf("服务端接收到的数据："+msg);
                    //返回
                    ByteBuffer buffer=ByteBuffer.allocate(256);
                    buffer.put("hello channel".getBytes(StandardCharsets.UTF_8));
                    buffer.flip();
                    channel.write(buffer);
                }

            }

        }
    }
}
